use std::rc::Rc;
use std::sync::Arc;

use tokio::fs::File;
use tokio::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::task::yield_now;

use crate::gen_title;

pub async fn ch7_1_1() {
    gen_title("ch7_1_1", 18);

    async fn say_to_world() -> String {
        String::from("world")
    }

    let op = say_to_world();
    println!("hello");
    println!("{}", op.await);
}

pub async fn ch7_1_2() {
    gen_title("ch7_1_2", 18);

    let handle = tokio::spawn(async { 10086 });

    let out = handle.await.unwrap();
    println!("GOT {}", out);
}

pub async fn ch7_1_3() {
    gen_title("ch7_1_3", 18);

    tokio::spawn(async {
        {
            let rc = Rc::new("hello");
            println!("{}", rc);
        }

        yield_now().await;
    });
}

pub async fn ch7_1_4() {
    gen_title("ch7_1_4", 18);

    tokio::spawn(async {
        let arc = Arc::new("hello");

        yield_now().await;

        println!("{}", arc);
    });
}

pub async fn ch7_1_5() -> io::Result<()> {
    gen_title("ch7_1_5", 18);

    let mut f = File::open("resources/poem.txt").await?;
    let mut buffer = [0; 10];

    let n = f.read(&mut buffer[..]).await?;

    println!("The bytes: {:?}", String::from_utf8(buffer.to_vec()));
    Ok(())
}

pub async fn ch7_1_6() -> io::Result<()> {
    gen_title("ch7_1_6", 18);

    let mut f = File::open("resources/poem.txt").await?;
    let mut buffer = Vec::new();

    f.read_to_end(&mut buffer).await?;

    println!("The bytes: {:?}", String::from_utf8(buffer));
    Ok(())
}

pub async fn ch7_1_7() -> io::Result<()> {
    let mut file = File::create("resources/foo.txt").await?;
    let n = file.write(b"some bytes").await?;
    println!("Wrote the first {} bytes of 'some bytes'.", n);
    Ok(())
}

pub async fn ch7_1_8() -> io::Result<()> {
    let mut file = File::create("resources/foo.txt").await?;

    file.write_all(b"some bytes").await?;
    Ok(())
}

pub async fn ch7_1_9() -> io::Result<()> {
    let mut reader: &[u8] = b"hello";
    let mut file = File::create("resources/foo.txt").await?;

    let n = io::copy(&mut reader, &mut file).await?;
    println!("Copied {} bytes.", n);
    Ok(())
}